// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Requests;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;
using Elastic.Transport.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.MachineLearning;

public sealed partial class UpdateDatafeedRequestParameters : RequestParameters
{
	/// <summary>
	/// <para>
	/// If <c>true</c>, wildcard indices expressions that resolve into no concrete indices are ignored. This includes the
	/// <c>_all</c> string or when no indices are specified.
	/// </para>
	/// </summary>
	public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

	/// <summary>
	/// <para>
	/// Type of index that wildcard patterns can match. If the request can target data streams, this argument determines
	/// whether wildcard expressions match hidden data streams. Supports comma-separated values. Valid values are:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <para>
	/// <c>all</c>: Match any data stream or index, including hidden ones.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>closed</c>: Match closed, non-hidden indices. Also matches any non-hidden data stream. Data streams cannot be closed.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>hidden</c>: Match hidden data streams and hidden indices. Must be combined with <c>open</c>, <c>closed</c>, or both.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>none</c>: Wildcard patterns are not accepted.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>open</c>: Match open, non-hidden indices. Also matches any non-hidden data stream.
	/// </para>
	/// </item>
	/// </list>
	/// </summary>
	public ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? ExpandWildcards { get => Q<ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>?>("expand_wildcards"); set => Q("expand_wildcards", value); }

	/// <summary>
	/// <para>
	/// If <c>true</c>, unavailable indices (missing or closed) are ignored.
	/// </para>
	/// </summary>
	public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }
}

internal sealed partial class UpdateDatafeedRequestConverter : JsonConverter<UpdateDatafeedRequest>
{
	public override UpdateDatafeedRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		if (reader.TokenType != JsonTokenType.StartObject)
			throw new JsonException("Unexpected JSON detected.");
		var variant = new UpdateDatafeedRequest();
		while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
		{
			if (reader.TokenType == JsonTokenType.PropertyName)
			{
				var property = reader.GetString();
				if (property == "aggregations")
				{
					variant.Aggregations = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.Aggregation>?>(ref reader, options);
					continue;
				}

				if (property == "chunking_config")
				{
					variant.ChunkingConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig?>(ref reader, options);
					continue;
				}

				if (property == "delayed_data_check_config")
				{
					variant.DelayedDataCheckConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig?>(ref reader, options);
					continue;
				}

				if (property == "frequency")
				{
					variant.Frequency = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Duration?>(ref reader, options);
					continue;
				}

				if (property == "indices" || property == "indexes")
				{
					variant.Indices = JsonSerializer.Deserialize<ICollection<string>?>(ref reader, options);
					continue;
				}

				if (property == "indices_options")
				{
					variant.IndicesOptions = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.IndicesOptions?>(ref reader, options);
					continue;
				}

				if (property == "job_id")
				{
					variant.JobId = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Id?>(ref reader, options);
					continue;
				}

				if (property == "max_empty_searches")
				{
					variant.MaxEmptySearches = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}

				if (property == "query")
				{
					variant.Query = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.QueryDsl.Query?>(ref reader, options);
					continue;
				}

				if (property == "query_delay")
				{
					variant.QueryDelay = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Duration?>(ref reader, options);
					continue;
				}

				if (property == "runtime_mappings")
				{
					variant.RuntimeMappings = JsonSerializer.Deserialize<IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeField>?>(ref reader, options);
					continue;
				}

				if (property == "script_fields")
				{
					variant.ScriptFields = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.ScriptField>?>(ref reader, options);
					continue;
				}

				if (property == "scroll_size")
				{
					variant.ScrollSize = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}
			}
		}

		return variant;
	}

	public override void Write(Utf8JsonWriter writer, UpdateDatafeedRequest value, JsonSerializerOptions options)
	{
		writer.WriteStartObject();
		if (value.Aggregations is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, value.Aggregations, options);
		}

		if (value.ChunkingConfig is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, value.ChunkingConfig, options);
		}

		if (value.DelayedDataCheckConfig is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, value.DelayedDataCheckConfig, options);
		}

		if (value.Frequency is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, value.Frequency, options);
		}

		if (value.Indices is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, value.Indices, options);
		}

		if (value.IndicesOptions is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, value.IndicesOptions, options);
		}

		if (value.JobId is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, value.JobId, options);
		}

		if (value.MaxEmptySearches.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(value.MaxEmptySearches.Value);
		}

		if (value.Query is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, value.Query, options);
		}

		if (value.QueryDelay is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, value.QueryDelay, options);
		}

		if (value.RuntimeMappings is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, value.RuntimeMappings, options);
		}

		if (value.ScriptFields is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, value.ScriptFields, options);
		}

		if (value.ScrollSize.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(value.ScrollSize.Value);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Update a datafeed.
/// You must stop and start the datafeed for the changes to be applied.
/// When Elasticsearch security features are enabled, your datafeed remembers which roles the user who updated it had at
/// the time of the update and runs the query using those same roles. If you provide secondary authorization headers,
/// those credentials are used instead.
/// </para>
/// </summary>
[JsonConverter(typeof(UpdateDatafeedRequestConverter))]
public sealed partial class UpdateDatafeedRequest : PlainRequest<UpdateDatafeedRequestParameters>
{
	public UpdateDatafeedRequest(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	public UpdateDatafeedRequest()
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningUpdateDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.update_datafeed";

	/// <summary>
	/// <para>
	/// If <c>true</c>, wildcard indices expressions that resolve into no concrete indices are ignored. This includes the
	/// <c>_all</c> string or when no indices are specified.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

	/// <summary>
	/// <para>
	/// Type of index that wildcard patterns can match. If the request can target data streams, this argument determines
	/// whether wildcard expressions match hidden data streams. Supports comma-separated values. Valid values are:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <para>
	/// <c>all</c>: Match any data stream or index, including hidden ones.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>closed</c>: Match closed, non-hidden indices. Also matches any non-hidden data stream. Data streams cannot be closed.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>hidden</c>: Match hidden data streams and hidden indices. Must be combined with <c>open</c>, <c>closed</c>, or both.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>none</c>: Wildcard patterns are not accepted.
	/// </para>
	/// </item>
	/// <item>
	/// <para>
	/// <c>open</c>: Match open, non-hidden indices. Also matches any non-hidden data stream.
	/// </para>
	/// </item>
	/// </list>
	/// </summary>
	[JsonIgnore]
	public ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? ExpandWildcards { get => Q<ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>?>("expand_wildcards"); set => Q("expand_wildcards", value); }

	/// <summary>
	/// <para>
	/// If <c>true</c>, unavailable indices (missing or closed) are ignored.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only
	/// with low cardinality data.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("aggregations")]
	public IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.Aggregation>? Aggregations { get; set; }

	/// <summary>
	/// <para>
	/// Datafeeds might search over long time periods, for several months or years. This search is split into time
	/// chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of
	/// these time chunks are calculated; it is an advanced configuration option.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("chunking_config")]
	public Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfig { get; set; }

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally
	/// search over indices that have already been read in an effort to determine whether any data has subsequently been
	/// added to the index. If missing data is found, it is a good indication that the <c>query_delay</c> is set too low and
	/// the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time
	/// datafeeds.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("delayed_data_check_config")]
	public Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfig { get; set; }

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time. The default value is
	/// either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket
	/// span. When <c>frequency</c> is shorter than the bucket span, interim results for the last (partial) bucket are
	/// written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value
	/// must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("frequency")]
	public Elastic.Clients.Elasticsearch.Duration? Frequency { get; set; }

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("indices")]
	public ICollection<string>? Indices { get; set; }

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("indices_options")]
	public Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptions { get; set; }
	[JsonInclude, JsonPropertyName("job_id")]
	public Elastic.Clients.Elasticsearch.Id? JobId { get; set; }

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("max_empty_searches")]
	public int? MaxEmptySearches { get; set; }

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch. Note that if you change the query, the analyzed data is also
	/// changed. Therefore, the time required to learn might be long and the understandability of the results is
	/// unpredictable. If you want to make significant changes to the source data, it is recommended that you
	/// clone the job and datafeed and make the amendments in the clone. Let both run in parallel and close one
	/// when you are satisfied with the results of the job.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("query")]
	public Elastic.Clients.Elasticsearch.QueryDsl.Query? Query { get; set; }

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("query_delay")]
	public Elastic.Clients.Elasticsearch.Duration? QueryDelay { get; set; }

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("runtime_mappings")]
	public IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeField>? RuntimeMappings { get; set; }

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("script_fields")]
	public IDictionary<string, Elastic.Clients.Elasticsearch.ScriptField>? ScriptFields { get; set; }

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("scroll_size")]
	public int? ScrollSize { get; set; }
}

/// <summary>
/// <para>
/// Update a datafeed.
/// You must stop and start the datafeed for the changes to be applied.
/// When Elasticsearch security features are enabled, your datafeed remembers which roles the user who updated it had at
/// the time of the update and runs the query using those same roles. If you provide secondary authorization headers,
/// those credentials are used instead.
/// </para>
/// </summary>
public sealed partial class UpdateDatafeedRequestDescriptor<TDocument> : RequestDescriptor<UpdateDatafeedRequestDescriptor<TDocument>, UpdateDatafeedRequestParameters>
{
	internal UpdateDatafeedRequestDescriptor(Action<UpdateDatafeedRequestDescriptor<TDocument>> configure) => configure.Invoke(this);

	public UpdateDatafeedRequestDescriptor(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningUpdateDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.update_datafeed";

	public UpdateDatafeedRequestDescriptor<TDocument> AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
	public UpdateDatafeedRequestDescriptor<TDocument> ExpandWildcards(ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? expandWildcards) => Qs("expand_wildcards", expandWildcards);
	public UpdateDatafeedRequestDescriptor<TDocument> IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);

	public UpdateDatafeedRequestDescriptor<TDocument> DatafeedId(Elastic.Clients.Elasticsearch.Id datafeedId)
	{
		RouteValues.Required("datafeed_id", datafeedId);
		return Self;
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private ICollection<string>? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument> QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only
	/// with low cardinality data.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Datafeeds might search over long time periods, for several months or years. This search is split into time
	/// chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of
	/// these time chunks are calculated; it is an advanced configuration option.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> ChunkingConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally
	/// search over indices that have already been read in an effort to determine whether any data has subsequently been
	/// added to the index. If missing data is found, it is a good indication that the <c>query_delay</c> is set too low and
	/// the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time
	/// datafeeds.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time. The default value is
	/// either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket
	/// span. When <c>frequency</c> is shorter than the bucket span, interim results for the last (partial) bucket are
	/// written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value
	/// must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> Indices(ICollection<string>? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> IndicesOptions(Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> JobId(Elastic.Clients.Elasticsearch.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch. Note that if you change the query, the analyzed data is also
	/// changed. Therefore, the time required to learn might be long and the understandability of the results is
	/// unpredictable. If you want to make significant changes to the source data, it is recommended that you
	/// clone the job and datafeed and make the amendments in the clone. Let both run in parallel and close one
	/// when you are satisfied with the results of the job.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument> descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor<TDocument> Query(Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> QueryDelay(Elastic.Clients.Elasticsearch.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor<TDocument> ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Update a datafeed.
/// You must stop and start the datafeed for the changes to be applied.
/// When Elasticsearch security features are enabled, your datafeed remembers which roles the user who updated it had at
/// the time of the update and runs the query using those same roles. If you provide secondary authorization headers,
/// those credentials are used instead.
/// </para>
/// </summary>
public sealed partial class UpdateDatafeedRequestDescriptor : RequestDescriptor<UpdateDatafeedRequestDescriptor, UpdateDatafeedRequestParameters>
{
	internal UpdateDatafeedRequestDescriptor(Action<UpdateDatafeedRequestDescriptor> configure) => configure.Invoke(this);

	public UpdateDatafeedRequestDescriptor(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningUpdateDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.update_datafeed";

	public UpdateDatafeedRequestDescriptor AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
	public UpdateDatafeedRequestDescriptor ExpandWildcards(ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? expandWildcards) => Qs("expand_wildcards", expandWildcards);
	public UpdateDatafeedRequestDescriptor IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);

	public UpdateDatafeedRequestDescriptor DatafeedId(Elastic.Clients.Elasticsearch.Id datafeedId)
	{
		RouteValues.Required("datafeed_id", datafeedId);
		return Self;
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private ICollection<string>? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only
	/// with low cardinality data.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Datafeeds might search over long time periods, for several months or years. This search is split into time
	/// chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of
	/// these time chunks are calculated; it is an advanced configuration option.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor ChunkingConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally
	/// search over indices that have already been read in an effort to determine whether any data has subsequently been
	/// added to the index. If missing data is found, it is a good indication that the <c>query_delay</c> is set too low and
	/// the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time
	/// datafeeds.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time. The default value is
	/// either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket
	/// span. When <c>frequency</c> is shorter than the bucket span, interim results for the last (partial) bucket are
	/// written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value
	/// must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor Indices(ICollection<string>? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor IndicesOptions(Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor JobId(Elastic.Clients.Elasticsearch.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch. Note that if you change the query, the analyzed data is also
	/// changed. Therefore, the time required to learn might be long and the understandability of the results is
	/// unpredictable. If you want to make significant changes to the source data, it is recommended that you
	/// clone the job and datafeed and make the amendments in the clone. Let both run in parallel and close one
	/// when you are satisfied with the results of the job.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor Query(Elastic.Clients.Elasticsearch.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor Query(Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public UpdateDatafeedRequestDescriptor Query(Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor QueryDelay(Elastic.Clients.Elasticsearch.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>.
	/// </para>
	/// </summary>
	public UpdateDatafeedRequestDescriptor ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}